<script setup lang="ts">
import { Edit } from '@element-plus/icons-vue';
import { cloneDeep } from 'lodash';
import { nextTick, ref, watch } from 'vue';

interface Option {
  label: string;
  value: string | number;
}

const props = defineProps<{
  modelValue?: (string | number)[];
  options?: Option[];
  placeholder?: string;
  createOption?: (data: {
    dictLabel: string;
    dictValue: number;
    dictSort: number;
  }) => Promise<Option>;
}>();

const emit = defineEmits(['update:modelValue', 'change']);

const isEditing = ref(false);
const editValue = ref<(string | number)[]>([]);
const selectRef = ref(null);
const localOptions = ref<Option[]>([]);
const isCreating = ref(false);

// ✅ 监听 modelValue 变化
watch(
  () => props.modelValue,
  (newVal) => {
    editValue.value = Array.isArray(newVal) ? [...newVal] : [];
  },
  { immediate: true }
);

// ✅ 监听 options 变化（初始化 + 更新）
watch(
  () => props.options,
  (newOpts) => {
    localOptions.value = Array.isArray(newOpts) ? [...newOpts] : [];
  },
  { immediate: true, deep: true }
);

const startEdit = () => {
  isEditing.value = true;
  nextTick(() => {
    const select: any = selectRef.value;
    if (!select) return;
    // 聚焦
    select.focus?.();
    // 展开下拉
    select.toggleMenu?.(true);
  });
};

const save = () => {
  const deep = cloneDeep(editValue.value);
  // 如果是0 默认填充成 未分类
  if (deep.length === 0) {
    deep.push('0');
  }

  emit('update:modelValue', deep);
  emit('change', deep);
  isEditing.value = false;
};

const cancel = () => {
  isEditing.value = false;
};

// ✅ 处理创建新选项
const handleCreate = async (label: string) => {
  if (!label || editValue.value.includes(label)) return;

  const exists = localOptions.value.some((opt) => opt.value === label);
  if (exists) return;

  if (isCreating.value) return;
  isCreating.value = true;

  try {
    const lastValue =
      localOptions.value.length > 0
        ? Number(localOptions.value[localOptions.value.length - 1].value)
        : 0;

    const newOption = await props.createOption?.({
      dictLabel: label,
      dictValue: lastValue + 1,
      dictSort: localOptions.value.length
    });

    if (newOption && !localOptions.value.some((o) => o.value === newOption.value)) {
      localOptions.value.push(newOption);
    }
  } catch (err) {
    console.warn(`创建选项 "${label}" 失败`, err);
  } finally {
    isCreating.value = false;
  }
};
</script>

<template>
  <div class="editable-multi-cell" @click="startEdit" @click.stop>
    <!-- 显示模式 -->
    <template v-if="!isEditing">
      <span class="cell-text">
        {{
          modelValue && modelValue.length
            ? modelValue
                .map((v) => {
                  const opt = (options || []).find((o) => o.value === v);
                  return opt ? opt.label : v;
                })
                .join(', ')
            : placeholder
        }}
      </span>
      <el-icon class="edit-hint">
        <Edit />
      </el-icon>
    </template>

    <!-- 编辑模式 -->
    <template v-else>
      <el-select
        ref="selectRef"
        v-model="editValue"
        multiple
        collapse-tags
        collapse-tags-tooltip
        style="width: 100%; cursor: pointer"
        size="small"
        filterable
        :loading="isCreating"
        @blur="save"
        @keyup.esc="cancel"
        @create="handleCreate"
        @click.stop
      >
        <!-- 
        default-first-option
       -->
        <el-option
          v-for="opt in localOptions"
          :key="opt.value"
          :label="opt.label"
          :value="opt.value"
        />
      </el-select>
    </template>
  </div>
</template>

<style lang="scss">
.editable-multi-cell {
  cursor: pointer;
}
</style>
